import axios from 'axios'
import type { AxiosRequestConfig, AxiosResponse } from 'axios'
import { getMessageInfo } from '@utils/help'

import { ElMessage } from 'element-plus'
import type { BaseResponse } from '@dts/common'

const instance = axios.create({
  baseURL: '/api',
  timeout: 15000
})

/** 拦截器 */
instance.interceptors.request.use(
  (config) => {
    return config
  },
  (err: any) => {
    return Promise.reject(err)
  }
)

instance.interceptors.response.use(
  (response: AxiosResponse) => {
    if (response.status === 200) {
      return response
    }
    return Promise.reject(response.data)
  },
  (err: any) => {
    const { response } = err
    // 请求已发出,但是看不在200范围
    if (response) {
      ElMessage({
        message: getMessageInfo(response.status),
        type: 'warning'
      })
      return Promise.reject(response.data)
    }

    // 其余情况
    ElMessage({
      message: '网络异常,请稍后再试!',
      type: 'warning'
    })
  }
)

/** 二次拦截 */
const requestInstance = <T = any>(config: AxiosRequestConfig): Promise<T> => {
  return new Promise((resolve, reject) => {
    instance.request<any, AxiosResponse<BaseResponse<T>>>(config).then((res) => {
      const data = res.data
      // buffer
      if (config.responseType === 'arraybuffer') {
        resolve(data as any)
      } else if (data.code != 200) {
        ElMessage({
          message: data.msg,
          type: 'error'
        })
        reject(data.msg)
      } else {
        resolve(data.data)
      }
    })
  })
}

/** GET封装 */
export const get = <T = any, U = any>(
  url: string,
  params?: U,
  config?: AxiosRequestConfig
): Promise<T> => {
  return requestInstance<T>({
    url,
    method: 'GET',
    params,
    ...config
  })
}

/** POST封装 */
export const post = <T = any, U = any>(
  url: string,
  data?: U,
  config?: AxiosRequestConfig
): Promise<T> => {
  return requestInstance<T>({
    url,
    method: 'POST',
    data,
    ...config
  })
}
